package com.meeting.y.controller;

import com.jfinal.core.Controller;
import com.jfinal.plugin.activerecord.Record;
import com.meeting.y.util.NumberTool;
import com.meeting.y.util.StringUtil;
import com.meeting.y.util.TimeUtil;
import org.apache.log4j.Logger;
import org.junit.Test;

import java.util.*;

//@QControllerUrl("/y/setm")
public class SetYmeetingAdminController extends Controller {

    // 10个老师 50个小朋友
    public static List<String> teachs = new ArrayList<String>();
    public static List<String> students = new ArrayList<String>();
    public static List<String> rooms = new ArrayList<String>();

    //最终数据存储地方
    public static Map<String, Map<String, List<String>>> calendar_class_studentteacherlist = new LinkedHashMap<String, Map<String, List<String>>>();
    //固定位置排课
    public static Map<String, List<String>> dayclass_fixed_studentTeacherlist = new LinkedHashMap<String, List<String>>();


    //规则1 学生课程排在一起 ：生成学生队列，两个在一组 不同老师 //通过优先老师，放入下一组优先 中
    public static String Ruel_1_studentThead = "Ruel_1_studentThead：学生队列，顺序排（一般2个排一起）";
    public static List<String> studentThead = new ArrayList<String>();

    //规则2 学生需要隔至少一天 再来，效果好：生成 禁止队列，为昨天学生列表，获取学生 前先校验
    public static String Ruel_2_dayStudents = "Ruel_2_dayStudents：学生需要隔至少一天 再来，效果好";
    public static Map<String, List<String>> dayStudents = new LinkedHashMap<String, List<String>>();

    //规则3  生成队列，循环
    //规则6 老师每天 4 节课：禁止队列，满了就加进去
    public static String Ruel_6_dayteacher_count = "Ruel_6_dayteacher_count:每天老师的节数（老师每天 4 节课）";
    public static Map<String, Integer> dayteacher_count = new LinkedHashMap<String, Integer>();

    //隐藏规则，一节课 一个老师 只能排一个
    public static String Ruel_dayclass_teacherslist = "Ruel_dayclass_teacherslist：一节课 一个老师 只能排一个";
    public static Map<String, List<String>> dayclass_teacherslist = new LinkedHashMap<String, List<String>>();
    //隐藏规则，一节课 一个学生 只能排一个
    public static String Ruel_dayclass_studentlist = "Ruel_dayclass_studentlist：一节课 一个学生 只能排一个";
    public static Map<String, List<String>> dayclass_studentlist = new LinkedHashMap<String, List<String>>();

    //规则5 优先同一个学生 同一个老师：生成 学生 老师对。如有数据，优先出来对应的老师。
    public static String Ruel_5_student_teacherCount = "Ruel_5_student_teacherCount：优先同一个学生 同一个老师：生成 学生 老师对";
    public static LinkedHashMap<String, LinkedHashMap<String, Integer>> student_teacherCount = new LinkedHashMap<String, LinkedHashMap<String, Integer>>();
    //规则6 学生 可以的时间段
    public static String Ruel_6_allowStudentTime = "Ruel_6_allowStudentTime：学生允许的时间段";
    public static LinkedHashMap<String ,List<String>> allowStudentTime = new LinkedHashMap<String, List<String>>();
    //规则7 老师 可以的时间段，考虑 陪读等
    public static String Ruel_7_allowTeacherTime = "Ruel_7_allowTeacherTime：老师允许的时间段";
    public static LinkedHashMap<String ,List<String>> allowTeacherTime = new LinkedHashMap<String, List<String>>();

    public static Integer DayClasses = 7;//每天的课时数
    public static Integer Days = 7;//每周的上课天数

    //规则8 设置新老师的督导老师，排课先判断督导老师是否有时间
    public static String Ruel_8_teacher_superTeachers = "Ruel_8_teacher_superTeachers：实习老师必须有督导老师";
    public static LinkedHashMap<String,List<String>> teacher_superTeachers = new LinkedHashMap<String, List<String>>();

    public static Integer Student_DayDefault_repeatCount = 2;//学生，每天默认连续上课
    //allow_dayStudent_repeatCount [student,Map[day,count]]
    public static String Ruel_9_allow_dayStudent_repeatCount = "Ruel_9_allow_dayStudent_repeatCount：允许学生每天连续排课节数";
    public static LinkedHashMap<String,HashMap<String,Integer>> allow_dayStudent_repeatCount = new LinkedHashMap<String, HashMap<String, Integer>>();

    public static Integer Teacher_DayDefault_repeatCount = -1;//老师，每天默认连续不限制
    //allow_dayTeacher_repeatCount [teacher,Map[day,count]]
    public static String Ruel_8_allow_dayTeacher_repeatCount = "Ruel_8_allow_dayTeacher_repeatCount：允许老师每天连续排课节数";
    public static LinkedHashMap<String,HashMap<String,Integer>> allow_dayTeacher_repeatCount = new LinkedHashMap<String, HashMap<String, Integer>>();


    public static Integer Student_WeekDefault_Count = 4;//学生，每周上课节数
    public static String Ruel_10_allow_weekStudent_Count = "Ruel_10_allow_weekStudent_Count：允许学生每周节数";
    public static LinkedHashMap<String,Integer> allow_weekStudent_Count = new LinkedHashMap<String, Integer>();

    public static Integer Teacher_WeekDefault_Count = 22;//老师，每周上课节数
    public static String Ruel_11_allow_WeekTeacher_Count = "Ruel_11_allow_WeekTeacher_Count：允许老师每周节数";
    public static LinkedHashMap<String,Integer> allow_WeekTeacher_Count = new LinkedHashMap<String, Integer>();



    public void setCalendar_fixed(String day,String classes,String student_teacher){
        Map<String, List<String>> dayclass = calendar_class_studentteacherlist.get(day);
        if(dayclass == null){
            dayclass = new LinkedHashMap<String, List<String>>();
            calendar_class_studentteacherlist.put(day, dayclass);
        }

        List<String> _student_teacher = dayclass.get(classes);
        if (_student_teacher == null) {
            _student_teacher = new ArrayList<String>();
            dayclass.put(classes,_student_teacher);
        }

        if(student_teacher.contains("_")){
            //判断 是否满足需求
            _student_teacher.add(student_teacher);
            //将固定的老师和学生 放入map中，后续优化配对的时候，不动这个固定
            List<String> fixed_studentTeacherlist = dayclass_fixed_studentTeacherlist.get(day+classes);
            if (fixed_studentTeacherlist == null) {
                fixed_studentTeacherlist = new LinkedList<String>();
                dayclass_fixed_studentTeacherlist.put(day+classes,fixed_studentTeacherlist);
            }
            fixed_studentTeacherlist.add(student_teacher);

            String _student = student_teacher.split("_")[0];
            String _tearcher = student_teacher.split("_")[1];
            Integer _dayteachercount = 0;
            _dayteachercount = dayteacher_count.get(day + _tearcher);
            dayteacher_count.put(day + _tearcher, _dayteachercount == null ? 1 : ++_dayteachercount);

            LinkedHashMap<String, Integer> teacherCount = student_teacherCount.get(_student);
            if(teacherCount ==null){
                teacherCount = new LinkedHashMap<String, Integer>();
                student_teacherCount.put(_student,teacherCount);
            }
            Integer _count = 1;
            if(teacherCount.keySet().contains(_tearcher)){
                _count = teacherCount.get(_tearcher)+1;
            }
            teacherCount.put(_tearcher,_count);

            List<String> _dayclass_teacherslist = dayclass_teacherslist.get(day + classes);
            if (_dayclass_teacherslist == null) {
                _dayclass_teacherslist = new ArrayList<String>();
                dayclass_teacherslist.put(day + classes, _dayclass_teacherslist);
            }
            List<String> _dayclass_studentlist = dayclass_studentlist.get(day + classes);
            if (_dayclass_studentlist == null) {
                _dayclass_studentlist = new ArrayList<String>();
                dayclass_studentlist.put(day + classes, _dayclass_studentlist);
            }

            System.out.println(day + classes + _student + "_" + _tearcher);
            if (!_dayclass_teacherslist.contains(_tearcher)) {
                _dayclass_teacherslist.add(_tearcher);
            }
            if (!_dayclass_studentlist.contains(_student)) {
                _dayclass_studentlist.add(_student);
            }
            List<String> _dayStudent = new ArrayList<String>();
            dayStudents.put(day, _dayStudent);

            if (!_dayStudent.contains(_student)) {//维护 //规则2
                _dayStudent.add(_student);
            }

        }
    }

    public void setTeachers(){
        teachs = new ArrayList<String>();

        String _teachers = getPara("teachers");//"代代,沐沐,小宇,雁子"
        List<String> _teachs = Arrays.asList(_teachers.split(","));

        /*teacher_superTeachers.put("代代",Arrays.asList("方方".split(",")));
        teacher_superTeachers.put("沐沐",Arrays.asList("方方".split(",")));
        teacher_superTeachers.put("小宇",Arrays.asList("方方".split(",")));
        teacher_superTeachers.put("雁子",Arrays.asList("方方".split(",")));*/

        if(studentThead.size() ==0) {
            for (String s : students) {
                studentThead.add(s);
                studentThead.add(s);
            }
        }

        teachs.addAll(_teachs);
        List<Map<String,Object>> _result = new ArrayList<Map<String, Object>>();
        Map _teas = new HashMap();
        _result.add(_teas);
        _teas.put("label","老师");
        List<Map> _ts = new ArrayList<Map>();
        _teas.put("options",_ts);
        int i = 0;
        for(String _tear:teachs){
            for(int day = 1;day<=Days;day++){
                Map _t = new HashMap();
                _t.put("value",i++);
                _t.put("label",_tear+"_day"+day);
                _ts.add(_t);
            }
        }
        renderJson(_result);
    }

    public void initDate(){
        //根据参数获取数据，设置老师，学生

        List<String> _teachs = Arrays.asList("代代,沐沐,小宇,雁子".split(","));
        teachs.addAll(_teachs);

        List<String> _students = Arrays.asList("齐齐,金陆川,杨然,刘耕岐,山谨源,任希杰,杨恩诺,王博涵".split(","));
        students.addAll(_students);

        teacher_superTeachers.put("代代",Arrays.asList("方方".split(",")));
        teacher_superTeachers.put("沐沐",Arrays.asList("方方".split(",")));
        teacher_superTeachers.put("小宇",Arrays.asList("方方".split(",")));
        teacher_superTeachers.put("雁子",Arrays.asList("方方".split(",")));

        //默认初始化
        if(teachs.size()==0){
            for (int i = 0; i < 10; i++) {
                teachs.add("师" + i);
                rooms.add("教室" + i);
            }
        }else{
            for (int i = 0; i < 10; i++) {//循环老师
                rooms.add("教室" + i);
            }
        }
        if(students.size()==0){
            for (int i = 0; i < 55; i++) {
                students.add("生" + i);
            }
        }

        if(studentThead.size() ==0){
            for (String s : students) {
                studentThead.add(s);
                studentThead.add(s);
            }
            for (String s : students) {
                studentThead.add(s);
                studentThead.add(s);
            }
            //规则4 每个学生 每周4节课：队列循环两次
        }

        List<String> _allstudent_dayclass = Arrays.asList("day1_class4,day1_class5".split(","));
        allowStudentTime.put("杨然",_allstudent_dayclass);

        List<String> _allteacher_dayclass = new ArrayList<String>();
        for(int i=1;i<=5;i++) {
            String _str = "day1_class4,day1_class5,day1_class6,day1_class7";
            _str = _str.replace("day1","day"+i);//5天 都是下午有空
            _allteacher_dayclass.addAll(Arrays.asList(_str.split(",")));
        }
        allowTeacherTime.put("代代",_allteacher_dayclass);
        allowTeacherTime.put("沐沐",_allteacher_dayclass);

        HashMap <String,Integer> _teacherRepeatCount = new HashMap<String, Integer>();
        _teacherRepeatCount.put("day1",2);
        _teacherRepeatCount.put("day2",2);
        _teacherRepeatCount.put("day3",2);
        _teacherRepeatCount.put("day4",2);
        _teacherRepeatCount.put("day5",2);
        _teacherRepeatCount.put("day6",2);
        _teacherRepeatCount.put("day7",2);
        allow_dayTeacher_repeatCount.put("代代",_teacherRepeatCount);
        allow_dayTeacher_repeatCount.put("沐沐",_teacherRepeatCount);
        allow_dayTeacher_repeatCount.put("小宇",_teacherRepeatCount);
        allow_dayTeacher_repeatCount.put("雁子",_teacherRepeatCount);


//        setCalendar_fixed("day1","class1","生1_师5");


    }

    public void clearData(){
        // 10个老师 50个小朋友
        teachs = new ArrayList<String>();
        students = new ArrayList<String>();
        rooms = new ArrayList<String>();

        //最终数据存储地方
        calendar_class_studentteacherlist = new LinkedHashMap<String, Map<String, List<String>>>();

        //规则1 学生课程排在一起 ：生成学生队列，两个在一组 不同老师 //通过优先老师，放入下一组优先 中
        studentThead = new ArrayList<String>();

        //规则2 学生需要隔至少一天 再来，效果好：生成 禁止队列，为昨天学生列表，获取学生 前先校验
        dayStudents = new LinkedHashMap<String, List<String>>();

        //规则3  生成队列，循环
        //规则6 老师每天 4 节课：禁止队列，满了就加进去
        dayteacher_count = new LinkedHashMap<String, Integer>();

        dayclass_teacherslist = new LinkedHashMap<String, List<String>>();
        dayclass_studentlist = new LinkedHashMap<String, List<String>>();

        //规则5 优先同一个学生 同一个老师：生成 学生 老师对。如有数据，优先出来对应的老师。
        student_teacherCount = new LinkedHashMap<String, LinkedHashMap<String, Integer>>();
        //规则6 学生可以的时间段
        allowStudentTime = new LinkedHashMap<String, List<String>>();
        //规则7 老师 可以的时间段，考虑 陪读等
        allowTeacherTime = new LinkedHashMap<String, List<String>>();
        //规则8 督导老师
        teacher_superTeachers = new LinkedHashMap<String, List<String>>();
    }

    @Test
    public void setCalendar() {
        clearData();
        initDate();

        /**
         * 2019年9月2日18:15:42：
         1.支持设置自定义排课，代码76行，增加逻辑，判断已有该老师，则进行下一个 ok

         2.设置优先配对的同学,支持页面设置 老师-学生 对。学生挑老师。--initData

         3.学生按照报名日期排序，支持页面位置调整
            --页面设置，每天【2】节排在一起，每周【4】节。--page
         4.设置学生-允许 day-class。优先排。例：周二周三3-4点 ok
            --每次获取学生，先判断 是否在 allowStudentTime <str student,List<str day_classs> > 中，如果在，在看时间是否合适。
         5.学生 不要三节 排在一起。
            --dayStudent_repeatCount ，默认 [student,count]
            --allow_dayStudent_repeatCount [student,Map[day,count]]

         6.老师排序，按照星级，支持页面位置调整。--老师排好序，分免费 普通 团体
         7.老师陪读设置,免费课 设置 --老师_陪读，学生不必填 。老师设置 默认 免费课。

         8.老师 允许day-calss 。3-4 4-5 5-6 ok
            --每次获取老师，先判断 是否在 allowTeacherTime <str teacher,List<str day_classs> >中，如果在，在看时间是否合适。

         9.新老师 不要三节 排在一起。
            --设置dayTeacher_repeatCount，如果为 【2】，则获取下一个老师 ，默认 [teacher,count]
            --allow_dayTeacher_repeatCount [teacher,Map[day,count]]
--------------------------------------------------------------------------------------
         调整方向
         背景：目前遇到的问题，如果学生少的情况，没有按照 学生优先，会将
         1.按照顺序，一个学生，一个老师，同时排两节
         2.每次顺序循环，导致 前面老师，总是排满，后面老师 只有在前面老师排满后 才轮上
         等等原因

         希望调整为手工指定，规则约定（固定规则 必须遵守，可选规则）
         目前有两个交互：一种 空白，选择的时候控制，第二种填好在修改
         我感觉第三种比较好：右边设置后，动态显示 和 支持调整。
         1.输入老师，直接排好老师，根据规则每节，每周 等等
         2.设置学生，节数

         --------------------------------------------------------
         四个老师
         代代 沐沐 小雨 燕子 老师
         代代 沐沐 每天上午需要 陪读 比较累
         下午 最好 3-4 4-5 5-6, 2-3最好不排，实在不行也可以排
         小雨 燕子 刚上，不要三节 排在一起。

         目前小朋友不挑老师，正式课挑的。
         每个小朋友 都有固定时间点。周二周三3-4点等等，周四周五 4-5点
         ----------------
         交互要设计下，之前的定性思维，要不全部手工排（累），要不全部自动排（不够灵活）
         *重新定位：辅助排。（1.空白，一个一个填，通过可选择项目控制； 清空
         *                  2.填充好，再修改节点；自动
         *                  3.按照天排，改前一天，后面的自动排的，会同步变
         *                  选择了老师，自动筛选出优选学生
         *                  再选择学生，出现 那些节课；按天
         *                  ）
调整方向-先用起来-----2019年10月8日11:27:20
     阶段1：
         1.实现数据导入 表结构完善设计
         2.实现自己课程微信小程序查看
         3.实现查询 固定时间段 哪些老师有空
            2019年10月28日13:48:34
            3.2 上线ok 2019年11月6日14:42:22
             c.查看当天之前的课程 ok
             b.导入课程问题，需要循环3个月份 季度末，工作日问题 ok
                1.节假日 如何替换，增加日期课程迁移功能 ok
                2.循环到季末，可以设置开始时间和结束时间，ok
                    查找下周第一个星期1，保存7天，然后根据参数 通过sql循环
                3.导入 覆盖问题，删除历史日期ok
             a 权限：老师，学生家长，管理员
                ok未认证，看到待认证页面 todo 新增新增wechat_user 记录，然后配置权限后，新增记录到 auth_user
                ok已认证：老师，看到自己的课程（自己孩子的课程，确认了不需要2019-11-8 11:29:14）
                        学生，只能看到自己的课程 (学生老师一样，老师可以看到 自己参与的会议室
                                                管理员 创建所有会议)
                        管理员，可以看到所有人，所有课，没有会议室的，设置默认会议室。可以修改。
                ok全局开启管理员模式
                ok还有个bug，管理员么有展示 申请页面，和绑定页面
                ok另bug 绑定人员已经解决
            d.ok增加了“生假、师假”
            f.ok功能介绍

     阶段2：2020年1月21日17:19:57
         1.实现调课 辅助支持
            原始需求：代课，加个，调课
                    （代课人自己复制，被代课删除）
                          复制
                                修改功能
         优3*老师可以对课，进行
                修改， 只能修改自己的，除了老师不能修改，其余均可修改（管理员都可以）。
                      保存前进行 冲突监测。（老师和学生 均需要没用课[必须]，教室是空闲[警告]。友情提醒 今天几节课，昨天几节课）
                复制，可以按照小朋友 进行查询，跳转到修改页面
                删除，弹出确认框，在删除
         优2*隐藏需求：我的会议列表，管理员可以任意查看 老师 学生，老师可以看自己的，和任意学生。学生家长，只能看自己。
                    控制按钮（老师和学生可以点击），显示显示 老师 ，还是 显示学生。
                    （默认 管理员看老师，老师 看学生，学生看老师）
         2.实现计算薪资辅助
             1.ok 导出课时表
         优1* 处理欠课表（新增字段 欠课，欠课编号，补课编号） 2020年1月21日17:02:58
         优6* 课程类型，互动评估...（已有字段 类型）类型：团课,1v1,秋季团,音乐课，认知课
            // 统计和计算薪资 可以用
            //todo 导入 如何处理。总感觉没人用，后面在看吧，好像是导出的类型里面有。页面能改吧。方便
         优1* 病假标签，可以应用到 老师，学生，各种情况
         优4*2.导出汇总信息 到课时表 //需要涉及
         优5*3.导出家长签到表 //拿到excel再处理

     阶段3：
         1.实现辅助排课
     阶段5：
         老师和家长互动

         */


        //循环每天，每节课，每个老师
        Iterator<String> iterator = studentThead.iterator();
        for (int day = 1; day < 8; day++) {//每周
            String _day = "day" + day;
            System.out.println("_day:"+_day);
            List<String> _preDayStydent = dayStudents.get("day" + (day - 1));
            if (_preDayStydent == null) {
                _preDayStydent = new ArrayList<String>();
            }
            List<String> _dayStudent = new ArrayList<String>();
            dayStudents.put(_day, _dayStudent);
            Map<String, List<String>> class_studentteacher = calendar_class_studentteacherlist.get(_day);
            if(class_studentteacher == null) {
                class_studentteacher = new LinkedHashMap<String, List<String>>();
                calendar_class_studentteacherlist.put(_day, class_studentteacher);
            }
            List<String> _preStudent = new ArrayList<String>();
            Iterator<String> _preStudentEach = _preStudent.iterator();
            LinkedHashMap<String, LinkedHashMap<String, Integer>> _pre_student_teacherCount = (LinkedHashMap<String, LinkedHashMap<String, Integer>>) student_teacherCount.clone();
            HashMap<String,String> dayTeacher_repeatCount = new HashMap<String, String>();//teacher, preclass_count
            HashMap<String,String> dayStudent_repeatCount = new HashMap<String, String>();//student, preclass_count
            for (int iclass = 1; iclass <= DayClasses; iclass++) {//每节课
                String _classs = "class" + iclass;
                System.out.println("_classs:"+_classs);
                List<String> _student_teacher = class_studentteacher.get(_classs);
                if (_student_teacher == null) {
                    _student_teacher = new ArrayList<String>();
                }


                List<String> _dayclass_teacherslist = dayclass_teacherslist.get(_day + _classs);
                if (_dayclass_teacherslist == null) {
                    _dayclass_teacherslist = new ArrayList<String>();
                    dayclass_teacherslist.put(_day + _classs, _dayclass_teacherslist);
                }
                List<String> _dayclass_studentlist = dayclass_studentlist.get(_day + _classs);
                if (_dayclass_studentlist == null) {
                    _dayclass_studentlist = new ArrayList<String>();
                    dayclass_studentlist.put(_day + _classs, _dayclass_studentlist);
                }

                //需要 do while循环 ，老师 和 学生 状态 均ok，  才设置下一个 //后续（没有老师 或者 没有学生 ）
                Iterator<String> teachreEach = teachs.iterator();

                List<String> _nextStudent = new ArrayList<String>();
                for (String _room : rooms) {//目前 room 和 teacher 等价，每个老师都有 教室。
                    System.out.println("_room："+_room);



                    boolean isTeacherOk = true;
                    boolean isNeedSuper = false;
                    boolean hasGap = false;
                    boolean hasGap_student = false;
                    //获取老师
                    String _tearcher = "";
                    String _super_tearcher = "";
                    Integer _dayteachercount = 0;
                    //获取优先级 单数 和 少的。 优先排了 师1，但是 后面有更合适的 老师。如何处理
                    int loopTeacTime = 0;
                    do {
                        isTeacherOk = true;
                        if (teachreEach.hasNext()) {
                            _tearcher = teachreEach.next();
                        } else {
                            teachreEach = teachs.iterator();
                            loopTeacTime++;
                            _tearcher = teachreEach.next();
                        }
                        System.out.println("_tearcher" + _tearcher);
                        if ("".equals(_tearcher)) {
                            System.out.println("------_tearcher="+_tearcher);
                        }

                        //allowStudentTime 学生如果不在自己的允许数据段，则获取下一个学生
                        if(allowTeacherTime.containsKey(_tearcher)){
                            List<String> _alltime = allowTeacherTime.get(_tearcher);
                            if(!_alltime.contains(_day+"_"+_classs)){
                                isTeacherOk = false;
                            }
                        }

                        if (_dayclass_teacherslist.contains(_tearcher)) {// 隐藏规则，一节课 一个老师 只能排一个
                            isTeacherOk = false;
                        }
                        _dayteachercount = dayteacher_count.get(_day + _tearcher);
                        if (_dayteachercount != null && _dayteachercount > 4) {//规则6 每天4节
                            isTeacherOk = false;
                        }
                        //陪读 比较特殊，其实是如何给 督导老师排课 ，
                        List<String> superTeachers = teacher_superTeachers.get(_tearcher);
                        if(superTeachers!=null && superTeachers.size()>0){//有督导
                            boolean hasSuper = false;
                            for(String _superTeach:superTeachers){
                                //判断督导老师是否有时间
                                if(_dayclass_teacherslist.contains(_superTeach)){//没时间
                                    continue;
                                }else {
                                    hasSuper = true;
                                    isNeedSuper = true;
                                    _super_tearcher = _superTeach;
                                    break;
                                }
                            }
                            if(!hasSuper){//未找到对应督导老师，进行下一个逻辑判断
                                isTeacherOk = false;
                            }
                        }

                        //连续排课是否满配置
                        Logger.getLogger(this.getClass()).debug(Ruel_8_allow_dayTeacher_repeatCount);
                        String _repeat = dayTeacher_repeatCount.get(_tearcher);
                        if(!StringUtil.isEmpty(_repeat) && isTeacherOk){//这里只判断，真正排课后，再维护数据
                            String [] _pre_count = _repeat.split("_");
                            if(_pre_count!=null && _pre_count.length>1 && allow_dayTeacher_repeatCount.containsKey(_tearcher)){
                                HashMap day_count = allow_dayTeacher_repeatCount.get(_tearcher);
                                Integer _count = NumberTool.safeToInteger(day_count.get(_day),Teacher_DayDefault_repeatCount);
                                if(!checkHasGap(_pre_count[0],_classs)){//如果没有间隙+1 看是否超出， 有间隙，后面重置0，否则+1
                                    Integer _now_count = Integer.valueOf(_pre_count[1]);
                                    if(_now_count+1>_count){
                                        isTeacherOk = false;
                                    }
                                }else {
                                    hasGap = true;
                                }
                            }
                        }

                        if(loopTeacTime>1 && !isTeacherOk){
                            //如果老师又循环了一遍，还是不行，则认为这节课没有合适的老师，继续下一节课
                            break;
                        }

                    } while (!isTeacherOk);

                    if(!isTeacherOk){ //如果没有合适老师，跳过所有教师，下一节
                        break;
                    }


                    //todo 如果是督导，学生也要安排 上免费课的学生

                    //获取学生
                    boolean isStudentsOk = true;
                    String _student = "";
                    do {
                        isStudentsOk = true;
                        int _getStudentType = 0;
                        if (_preStudentEach.hasNext()) { // todo 解决 如果 学生第一节课已经有了，将改学生 放入第二列 需要排的列表中，达到一个学生两节课，排在一起
                            _student = _preStudentEach.next();
                            System.out.println("pre-" + _student);
                            _getStudentType = 1;
                        } else if (iterator.hasNext()) {
                            _student = iterator.next();
                            System.out.println("thread-" + _student);
                            _getStudentType = 2;
                        }
                        if ("生1".equals(_student)) {
                            System.out.println("------_student="+_student);
                        }

                        if(!_preStudentEach.hasNext() && !iterator.hasNext()){
                            continue;
                        }

                        //allowStudentTime 学生如果不在自己的允许数据段，则获取下一个学生
                        if(allowStudentTime.containsKey(_student)){
                            List<String> _alltime = allowStudentTime.get(_student);
                            if(!_alltime.contains(_day+"_"+_classs)){
                                _nextStudent.add(_student);
                                isStudentsOk = false;
                            }
                        }

                        if (_dayclass_studentlist.contains(_student) ) {// 隐藏规则，一节课 一个学生 只能排一个
                            _nextStudent.add(_student);
                            isStudentsOk = false;
                            System.out.println("remove1-" + _student);
                        }else if (_preDayStydent.contains(_student)) {//规则2 学生至少隔天参加
                            _nextStudent.add(_student);
                            isStudentsOk = false;
                            System.out.println("remove2-" + _student);
                        }

                        //连续排课是否满配置
                        Logger.getLogger(this.getClass()).debug(Ruel_9_allow_dayStudent_repeatCount);
                        String _repeat = dayStudent_repeatCount.get(_student);
                        if(!StringUtil.isEmpty(_repeat) && isTeacherOk){//这里只判断，真正排课后，再维护数据
                            String [] _pre_count = _repeat.split("_");
                            if(_pre_count!=null && _pre_count.length>1 && allow_dayStudent_repeatCount.containsKey(_student)){
                                HashMap day_count = allow_dayStudent_repeatCount.get(_student);
                                Integer _count = NumberTool.safeToInteger(day_count.get(_day),Student_DayDefault_repeatCount);
                                if(!checkHasGap(_pre_count[0],_classs)){//如果没有间隙+1 看是否超出， 有间隙，后面重置0，否则+1
                                    Integer _now_count = Integer.valueOf(_pre_count[1]);
                                    if(_now_count+1>_count){
                                        isStudentsOk = false;
                                    }
                                }else {
                                    hasGap_student = true;
                                }
                            }
                        }


                        if (isStudentsOk) {
                            if (_getStudentType == 1) {
                                _preStudentEach.remove();
                            } else if (_getStudentType == 2) {
                                iterator.remove();
                            }
                        }

                    }
                    while (!isStudentsOk);

                    if(StringUtil.isStrEmpty(_student)){//这里没有学生了
                        break;
                    }

                    //排课
                    _student_teacher.add(_student + "_" + _tearcher);
                    _student_teacher.add(_tearcher + "_" + _super_tearcher);//这里展示“实习老师_督导老师”

                    dayteacher_count.put(_day + _tearcher, _dayteachercount == null ? 1 : ++_dayteachercount);

                    LinkedHashMap<String, Integer> teacherCount = student_teacherCount.get(_student);
                    if(teacherCount ==null){
                        teacherCount = new LinkedHashMap<String, Integer>();
                        student_teacherCount.put(_student,teacherCount);
                    }
                    Integer _count = 1;
                    if(teacherCount.keySet().contains(_tearcher)){
                        _count = teacherCount.get(_tearcher)+1;
                    }
                    teacherCount.put(_tearcher,_count);

                    System.out.println(_day + _classs + _student + "_" + _tearcher);
                    if (!_dayclass_teacherslist.contains(_tearcher)) {
                        _dayclass_teacherslist.add(_tearcher);
                    }

                    if (!_dayclass_studentlist.contains(_student)) {
                        _dayclass_studentlist.add(_student);
                    }

                    if (!_dayStudent.contains(_student)) {//维护 //规则2
                        _dayStudent.add(_student);
                    }
                    Integer _repeatCount = 1;
                    if(dayTeacher_repeatCount.containsKey(_tearcher) && !hasGap){//有内容，并且没有间隙 需要加1
                        _repeatCount = Integer.valueOf(dayTeacher_repeatCount.get(_tearcher).split("_")[1])+1;
                    }
                    dayTeacher_repeatCount.put(_tearcher,_classs+"_"+_repeatCount);

                    Integer _repeatCount_student = 1;
                    if(dayStudent_repeatCount.containsKey(_student) && !hasGap_student){//有内容，并且没有间隙 需要加1
                        _repeatCount_student = Integer.valueOf(dayStudent_repeatCount.get(_student).split("_")[1])+1;
                    }
                    dayStudent_repeatCount.put(_student,_classs+"_"+_repeatCount_student);



                    //目前只处理了督导 一节，只能督导一个人的逻辑
                    if(isNeedSuper){
                        if (!_dayclass_teacherslist.contains(_super_tearcher)) {
                            _dayclass_teacherslist.add(_super_tearcher);
                        }
                    }


                    if (isTeacherOk) {
//                        teachreEach.remove();
                    }


                }
                if(_day.equals("day3") && _classs.equals("class3")){
                    System.out.println(_day + _classs);
                }
                //设置学生 尽量同一个老师 //要排除掉 fixed 的客户
                List<String> fixed_studentTeacherlist = dayclass_fixed_studentTeacherlist.get(day+_classs);
                _student_teacher = this.setSameTeac(_student_teacher,_pre_student_teacherCount,fixed_studentTeacherlist);
                class_studentteacher.put(_classs, _student_teacher);
                _preStudentEach = _nextStudent.iterator();

            }
        }

        //processData 输出
        String _searchKey = getPara("key");
        List<Record> _re = new ArrayList<Record>();
        int _day = 0;
        for (String day : calendar_class_studentteacherlist.keySet()) {
            System.out.println("out-day:"+day);
            Map<String, List<String>> class_studentteacherlist = calendar_class_studentteacherlist.get(day);
            Record record = new Record();
            record.set("date", TimeUtil.getPreOrNextDay("",_day++));
            for (String iclass : class_studentteacherlist.keySet()) {
                System.out.print(iclass);
                List<String> _st = class_studentteacherlist.get(iclass);
                System.out.println("class-student:" + _st.toString());
                List<String> _rest = new ArrayList<String>();
                if(StringUtil.isStrEmpty(_searchKey)){
                    _rest = _st;
                }else {
                    for (String _st_str:_st) {
                        String _end = "";
                        if(_searchKey.contains("生") && !_searchKey.contains("_")){
                            _end = "_";
                        }
                        if(_st_str.contains(_searchKey+_end)){
                            _rest.add(_st_str);
                        }
                    }
                }
                record.set(iclass,_rest);
            }
            _re.add(record);

        }
        renderJson(_re);

    }

    public static boolean checkHasGap(String preClass,String nowClass){
        if("3".equals(preClass)){//中午 算有间隙
            return true;
        }
        Integer _pre = Integer.valueOf(preClass.replace("class",""));
        Integer _now = Integer.valueOf(nowClass.replace("class",""));
        if(_now-_pre > 1 ){//如果两课中间 有大于一节，算有间隙
            return true;
        }

        return false;
    }


    /**
     * 将一节的所有学生 配过对老师的按照次数进行排序，最熟悉的优先排对。可以将 已有对，优先排在一起
     * @param _student_teacher 一节课 所有老师和学生
     * @param student_teacherCount 学生-老师 配对次数
     * @return
     */
    public static List<String> setSameTeac(List<String> _student_teacher,Map<String, LinkedHashMap<String, Integer>> student_teacherCount,List<String> fixed_studentTeacherlist)
    {
        List<String> _result= new ArrayList<String>();
        Map<String,String> _studentTeacherMap = new HashMap<String, String>();//将学生 和 老师 放入map中
        for(String _s_t :_student_teacher){//获取需要排序的学生
            if(!StringUtil.isStrEmpty(_s_t)){
                String[] _arr = _s_t.split("_");
                if(_arr.length>1) {
                    _studentTeacherMap.put(_arr[0], _arr[1]);
                }
            }
        }

        LinkedHashMap<String, LinkedHashMap<String, Integer>> _sort_student_teacherCount = new LinkedHashMap<String, LinkedHashMap<String, Integer>>();
        for(String _st: _studentTeacherMap.keySet()){//整理 排序的老师数量 进入新的map
            if(student_teacherCount.containsKey(_st)){
                _sort_student_teacherCount.put(_st,student_teacherCount.get(_st));
            }
        }
        //排序
        _sort_student_teacherCount = SortMapValue_size(_sort_student_teacherCount,"");
        Iterator<String> _stu_set_iter = _sort_student_teacherCount.keySet().iterator();
//        Set<String> _sutdent_ready = _studentTeacherMap.keySet();
//        Collection<String> _teac_ready = _studentTeacherMap.values();

        List<String> _sutdent_ready = deepCloneMap(_studentTeacherMap,"key");
        List<String> _teac_ready = deepCloneMap(_studentTeacherMap,"value");
        //处理fixed
        if(fixed_studentTeacherlist != null) {
            for (String _stu_teac : fixed_studentTeacherlist) {//循环 固定配置的课
                String[] _arr = _stu_teac.split("_");
                if (_arr.length > 1) {
                    String _stu = _arr[0];//获取学生
                    String _teac = _arr[1];//获取老师
                    if (_sutdent_ready.contains(_stu) && _teac_ready.contains(_teac)) {//确保都存在（应该都存在的）
                        _result.add(_stu_teac);//直接加入返回列表中
                        _sutdent_ready.remove(_stu);//待删除列表中，删除对应学生
                        _teac_ready.remove(_teac);//待删除列表中，删除对应老师
                    }
                }
            }
        }


        while (_stu_set_iter.hasNext()){//循环学生
            String _student = _stu_set_iter.next();//获取学生
            LinkedHashMap<String, Integer> _teas = _sort_student_teacherCount.get(_student);//获取学生的 老师配对次数列表Map
            for(String _tech: _teas.keySet()){//循环排序后的老师
                if(_teac_ready.contains(_tech)){//如果 当前的老师列表中，包含循环的已配的老师
                    _result.add(_student+"_"+_tech);//放入新的队列
                    _sutdent_ready.remove(_student);//待删除列表中，删除对应学生
                    _teac_ready.remove(_tech);//待删除列表中，删除对应老师
                    break;//循环下一个学生
                }
            }
        }
        Iterator<String> _remove_tech =  _teac_ready.iterator();
        for(String _students:_sutdent_ready){//循环 剩下的学生
            if(_remove_tech.hasNext()) {//在剩下的老师中，获取排对
                _result.add(_students + "_" + _remove_tech.next());
            }
        }

        return _result;
    }

    public static List<String> deepCloneMap(Map<String,String> src,String type){
        List<String> des=new ArrayList<String>();
        for(Iterator<String> it=src.keySet().iterator();it.hasNext();){
            String key=it.next();
            String value=src.get(key);
            if("key".equals(type)){
                des.add(key);
            }else {
                des.add(value);
            }
        }
        return des;
    }

    /**
     * 排序 map的value size排序，按照 单数 优先，再按照大小
     * @param oldMap
     * @param type
     * @return
     */
    public static LinkedHashMap SortMapValue_size(LinkedHashMap<String, LinkedHashMap<String, Integer>> oldMap, final String type){
        ArrayList<Map.Entry<String, LinkedHashMap<String, Integer>>> list = new ArrayList<Map.Entry<String, LinkedHashMap<String, Integer>>>(oldMap.entrySet());
        Collections.sort(list, new Comparator<Map.Entry<String, LinkedHashMap<String, Integer>>>() {
            public int compare(Map.Entry<String, LinkedHashMap<String, Integer>> arg0,
                               Map.Entry<String, LinkedHashMap<String, Integer>> arg1) {
                if(type.equals("desc")){
                    return arg1.getValue().size() - arg0.getValue().size();
                }
                return arg0.getValue().size() - arg1.getValue().size();
            }
        });
        LinkedHashMap newMap = new LinkedHashMap();
        for (int i = 0; i < list.size(); i++) {
            LinkedHashMap<String, Integer> _resultValue = list.get(i).getValue();
            SortMapValue(_resultValue,"");
            newMap.put(list.get(i).getKey(), _resultValue);
        }
        return newMap;
    }

    /**
     * 按照map value排序
     * @param oldMap
     * @param type
     * @return
     */
    public static LinkedHashMap SortMapValue(LinkedHashMap<String, Integer> oldMap, final String type){
        ArrayList<Map.Entry<String, Integer>> list = new ArrayList<Map.Entry<String, Integer>>(oldMap.entrySet());
        Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
            public int compare(Map.Entry<String, Integer> arg0,
                               Map.Entry<String, Integer> arg1) {
                if(type.equals("desc")){
                    return arg1.getValue() - arg0.getValue();
                }
                return arg0.getValue() - arg1.getValue();
            }
        });
        LinkedHashMap newMap = new LinkedHashMap();
        for (int i = 0; i < list.size(); i++) {
            newMap.put(list.get(i).getKey(), list.get(i).getValue());
        }
        return newMap;
    }

    /**
     * 排序 map的value，按照 单数 优先，再按照大小
     * @param oldMap
     * @param type
     * @return
     */
    public static LinkedHashMap SortMapValue_Odd1st(LinkedHashMap<String, Integer> oldMap, final String type){
        ArrayList<Map.Entry<String, Integer>> list = new ArrayList<Map.Entry<String, Integer>>(oldMap.entrySet());
        Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
            public int compare(Map.Entry<String, Integer> arg0,
                                 Map.Entry<String, Integer> arg1) {
                if(type.equals("desc")){
                    if(arg0.getValue()%2 != arg1.getValue()%2){
                        return arg1.getValue()%2 - arg0.getValue()%2;//奇数优先，然后再比大小
                    }
                    return arg1.getValue() - arg0.getValue();
                }
                if(arg0.getValue()%2 != arg1.getValue()%2){
                    return arg0.getValue()%2 - arg1.getValue()%2;//奇数优先，然后再比大小
                }
                return arg0.getValue() - arg1.getValue();
            }
        });
        LinkedHashMap newMap = new LinkedHashMap();
        for (int i = 0; i < list.size(); i++) {
            newMap.put(list.get(i).getKey(), list.get(i).getValue());
        }
        return newMap;
    }

    public static void main(String[] args) throws Exception {
        // TODO code application logic here
        LinkedHashMap<String, Integer> myMap = new LinkedHashMap();
        myMap.put("1", 1);
        myMap.put("2", 4);
        myMap.put("3", 3);
        myMap.put("4", 9);
        myMap.put("5", 6);
        myMap.put("6", 2);

        printMap(myMap);

        myMap = SortMapValue_Odd1st(myMap,"desc");

        printMap(myMap);
    }

    private static void printMap(Map map){
        Logger.getLogger("printMap").debug("===================mapStart==================");
        Iterator it = map.entrySet().iterator();
        while(it.hasNext()){
            Map.Entry entry = (Map.Entry) it.next();
            Logger.getLogger("printMap").debug(entry.getKey() + ":" + entry.getValue());
        }
        Logger.getLogger("printMap").debug("===================mapEnd==================");
    }


    @Test
    public void testList() {

        List<String> rooms = new ArrayList<String>();
        List<String> nextrooms = new ArrayList<String>();

        for (int i = 0; i < 10; i++) {
            rooms.add("教室" + i);
            if (i % 2 == 0) {
                nextrooms.add("教室" + i);
            }
        }

//        for(int j=0;j<2;j++){
        Iterator<String> iterator = rooms.iterator();
        Iterator<String> nextiterator = null;
        for (int i = 0; i < 10; i++) {
            String s = "";
            s = iterator.next();
            if (i % 2 == 0) {
                System.out.println(s);
            } else {
                nextrooms.add(s);
                iterator.remove();
                nextiterator = nextrooms.iterator(); //如果使用迭代器，如果list发生变化，需要重新设置迭代器，否则会执行被修改不一致报错。
            }
            System.out.println(s + " a");
        }


        for (int i = 0; i < 6; i++) {
            String s = "";
            if (nextiterator.hasNext()) {
                s = nextiterator.next();
                if (i % 2 == 0) {
                    System.out.println(s);
                } else {
                    nextiterator.remove();
                }
            }
            System.out.println(s + " a");
        }

            /*for(int i=0;i<10;i++){
                String s ="";
                if(nextiterator.hasNext()){
                    s = nextiterator.next();
                }else {
                    s = iterator.next();
                }
                if(i%2 == 0 ){
                    System.out.println(s);
                }else{
                    nextrooms.add(s);
                    iterator.remove();
                }
                System.out.println(s+" a");
            }*/
//        }

    }

    public static List<String> getTeachs() {
        return teachs;
    }

    public static void setTeachs(List<String> teachs) {
        SetYmeetingAdminController.teachs = teachs;
    }

    public static List<String> getStudents() {
        return students;
    }

    public static void setStudents(List<String> students) {
        SetYmeetingAdminController.students = students;
    }

    public static List<String> getRooms() {
        return rooms;
    }

    public static void setRooms(List<String> rooms) {
        SetYmeetingAdminController.rooms = rooms;
    }

    public static Map<String, Map<String, List<String>>> getCalendar_class_studentteacherlist() {
        return calendar_class_studentteacherlist;
    }

    public static void setCalendar_class_studentteacherlist(Map<String, Map<String, List<String>>> calendar_class_studentteacherlist) {
        SetYmeetingAdminController.calendar_class_studentteacherlist = calendar_class_studentteacherlist;
    }

    public static Map<String, List<String>> getDayclass_fixed_studentTeacherlist() {
        return dayclass_fixed_studentTeacherlist;
    }

    public static void setDayclass_fixed_studentTeacherlist(Map<String, List<String>> dayclass_fixed_studentTeacherlist) {
        SetYmeetingAdminController.dayclass_fixed_studentTeacherlist = dayclass_fixed_studentTeacherlist;
    }

    public static List<String> getStudentThead() {
        return studentThead;
    }

    public static void setStudentThead(List<String> studentThead) {
        SetYmeetingAdminController.studentThead = studentThead;
    }

    public static Map<String, List<String>> getDayStudents() {
        return dayStudents;
    }

    public static void setDayStudents(Map<String, List<String>> dayStudents) {
        SetYmeetingAdminController.dayStudents = dayStudents;
    }

    public static Map<String, Integer> getDayteacher_count() {
        return dayteacher_count;
    }

    public static void setDayteacher_count(Map<String, Integer> dayteacher_count) {
        SetYmeetingAdminController.dayteacher_count = dayteacher_count;
    }

    public static Map<String, List<String>> getDayclass_teacherslist() {
        return dayclass_teacherslist;
    }

    public static void setDayclass_teacherslist(Map<String, List<String>> dayclass_teacherslist) {
        SetYmeetingAdminController.dayclass_teacherslist = dayclass_teacherslist;
    }

    public static Map<String, List<String>> getDayclass_studentlist() {
        return dayclass_studentlist;
    }

    public static void setDayclass_studentlist(Map<String, List<String>> dayclass_studentlist) {
        SetYmeetingAdminController.dayclass_studentlist = dayclass_studentlist;
    }

    public static LinkedHashMap<String, LinkedHashMap<String, Integer>> getStudent_teacherCount() {
        return student_teacherCount;
    }

    public static void setStudent_teacherCount(LinkedHashMap<String, LinkedHashMap<String, Integer>> student_teacherCount) {
        SetYmeetingAdminController.student_teacherCount = student_teacherCount;
    }

    public static LinkedHashMap<String, List<String>> getAllowStudentTime() {
        return allowStudentTime;
    }

    public static void setAllowStudentTime(LinkedHashMap<String, List<String>> allowStudentTime) {
        SetYmeetingAdminController.allowStudentTime = allowStudentTime;
    }

    public static LinkedHashMap<String, List<String>> getAllowTeacherTime() {
        return allowTeacherTime;
    }

    public static void setAllowTeacherTime(LinkedHashMap<String, List<String>> allowTeacherTime) {
        SetYmeetingAdminController.allowTeacherTime = allowTeacherTime;
    }
}
